home *** CD-ROM | disk | FTP | other *** search
- #include "slang.h"
- #include "nret.h"
- //////////////////////////
- int Slang::get_argument(double* x)
- {
- /* get_token(); // line argument
- if(token_type != VARIABLE && token_type != NUMBER
- && token_type != COMMAND && token[0] != '-')
- return 1;
- putback();
- */
- get_exp(x);
- return 0;
- }
- ////////////////////////////////
- char* Slang::get_exp(double* result)
- {
- if(error)
- return NULL;
-
- char* str_value;
- get_token();
- if(!*token)
- { serror(2); return NULL; }
- str_value = level2(result);
- return str_value;
- }
- ////////////////////////
- char* Slang::level2(double* result)
- {
- if(error)
- return NULL;
-
- char op; char* str_value;
- double hold;
- str_value = level3(result);
- while((op = *token) == '+' || op == '-')
- {
- get_token();
- str_value = level3(&hold); // str_value = !!!
- arith(op, result, &hold);
- }
- return str_value;
- }
- //////////////////////////
- char* Slang::level3(double* result)
- {
- if(error)
- return NULL;
-
- register char op; char* str_value;
- double hold;
- str_value = level4(result);
- while((op = *token) == '*' || op == '/' || op == '%')
- {
- get_token();
- str_value = level4(&hold); // str_value = !!!
- arith(op, result, &hold);
- }
- return str_value;
- }
- //////////////////////////
- char* Slang::level4(double* result)
- {
- if(error)
- return NULL;
-
- double hold; char* str_value;
- str_value = level5(result);
- if(*token == '^')
- {
- get_token();
- str_value = level4(&hold); // str_value = !!!!
- arith('^', result, &hold);
- }
- return str_value;
- }
- //////////////////////////
- char* Slang::level5(double* result)
- {
- if(error)
- return NULL;
-
- register char op; char* str_value;
- op = 0;
- if((token_type == DELIMITER) && *token == '+' || *token == '-')
- {
- op = *token;
- get_token();
- }
- str_value = level6(result);
- if(op)
- unary(op, result);
- return str_value;
- }
- ////////////////////////////
- char* Slang::level6(double* result)
- {
- if(error)
- return NULL;
-
- if((*token == '(') && (token_type == DELIMITER))
- {
- get_token();
- level2(result);
- if(*token != ')')
- { serror(1); return NULL; }
- get_token();
- }
- // else
- {
- return level7(result);
- }
- }
-
-
- ///////////////////////////
- char* Slang::level7(double* result)
- {
- if(error)
- return NULL;
-
- if(*token == '@') // write alse possibility of retusn STR
- {
- gosub();
- *result = variables->find("retval")->d;
- get_token();
- variable_type = REAL;
- return NULL;
- }
- else
- {
- if(*prog == '[')
- {
- // putback();
- delete theName;
- theName = strdup(token);
- get_token(); // '['
- get_token(); // index expression
- level2(result);
- if(*token != ']')
- { serror(19); return NULL; }
- // get_token();
- token_type = VARIABLE;
- strcpy(token, theName);
- }
-
- return primitive(result);
- }
- }
-
-
- ///////////////////////////
- char* Slang::primitive(double * result)
- {
- if(error)
- return NULL;
- switch(token_type)
- {
- case VARIABLE:
- Variable* v;
- v = variables->find(token);
- variable_type = v->type;
- switch(v->type)
- {
- case REAL:
- *result = v->d;
- get_token(); return NULL;
- case ARRAY:
- *result = v->da[(int)(*result)];
- get_token();
- return NULL;
- case STR :
- *result = v->d;
- char* str_value = v->s;
- get_token();
- return str_value;
- }
- return 0;
- case NUMBER:
- char* endptr;
- *result = strtod(token, &endptr);
- get_token();
- variable_type = REAL;
- return NULL;
- case COMMAND:
- math(result); get_token(); return NULL;
- default:
- // serror(0);
- return NULL;
- }
- }
- //////////////////////////////
- void Slang::arith(char o, double* r, double* h)
- {
- if(error)
- return;
-
- double t, ex;
- switch(o)
- {
- case '-':
- *r = *r - *h;
- break;
- case '+':
- *r = *r + *h;
- break;
- case '*':
- *r = *r * *h;
- break;
- case '/':
- *r = (*r) / (*h);
- break;
- case '%':
- t = (*r) / (*h);
- *r = *r - (t * (*h));
- break;
- case '^':
- ex = *r;
- *r = pow(ex, *h);
- break;
- }
- }
- ///////////////////////
- void Slang::unary(char o, double* r)
- {
- if(o == '-')
- *r = -(*r);
- }
- /////////////////////////////
- void Slang::error_report(char* text) // Overload for your own print
- {
- printf("%s", text);
- }
- /////////////////////
- void Slang::serror(int err)
- {
- char c = prog[0]; // Get line number
- prog[0] = '\0';
- char ln[5];
- itoa(nRet(program) + 1, ln, 10);
- prog[0] = c;
-
- int l; // line: 10; file: work.vec
- char s[160];
- char* s1 = s;
- strcpy(s1, "line: ");
- s1 += 6; // strlen("line: ");
- strcpy(s1, ln);
- s1 += strlen(ln);
- strcpy(s1, "\nfile: ");
- s1 += 7;
- strcpy(s1, playstack[play_used]->prog);
- s1 += strlen(playstack[play_used]->prog);
- strcpy(s1, "\n");
- s1++;
- strcpy(s1, error_string[err]);
- error_report(s);
- error = 1;
- }
- //////////////////////////
- int Slang::get_token()
- {
- if(error)
- return NULL;
-
- char* temp;
- token_type = 0; tok = 0;
- temp = token;
- if(*prog == '\0')
- {
- *token = 0;
- tok = FINISHED;
- return(token_type = DELIMITER);
- }
- while(iswhite(*prog))
- ++prog;
- if(*prog == '/' && *(prog + 1) == '*' && *prog + 1) // Remarked block
- {
- while(1)
- {
- if(*prog == '*' && *(prog + 1) == '/')
- {
- tok = REMARK_BLOCK;
- prog += 2;
- return token_type = STRING;
- }
- else if(!(*(prog + 1))) // End of remarked block
- {
- tok = FINISHED;
- return token_type = DELIMITER;
- }
- *prog++;
- }
- }
-
- switch(*prog)
- {
- case '&':
- tok = REMARK;
- find_eol();
- return(token_type = STRING);
- case '@':
- tok = GOSUB;
- *temp++ = *prog++;
- return(token_type = ALPHA);
- case '!':
- tok = LABEL;
- *temp++ = *prog++;
- return(token_type = ALPHA);
- case ':' :
- case '\r':
- char c = prog[0];
- ++prog;
- if((*prog != '\0') && (c != ':'))
- ++prog;
- tok = EOL; *token = '\r';
- token[1] = '\n'; token[2] = 0;
- return(token_type = DELIMITER);
- case '"':
- prog++;
- while(*prog != '"' && *prog != '\r')
- *temp++ = *prog++;
- if(*prog == '\r')
- { serror(14); return 0; }
- prog++; *temp = 0;
- return(token_type = QUOTE);
- }
- if(strchr("<>=", *prog) && strchr("<>=", *(prog + 1)))
- {
- *temp++ = *prog++;
- *temp++ = *prog++;
- *temp = 0;
- return(token_type = DELIMITER);
- }
- if(strchr(" +-^/*%=;(),<>[]", *prog))
- {
- *temp = *prog;
- prog++;
- temp++;
- *temp = 0;
- return(token_type = DELIMITER);
- }
-
- if(isdigit(*prog))
- {
- while(!isdelim(*prog))
- *temp++ = *prog++;
- *temp = '\0';
- return(token_type = NUMBER);
- }
- if(isalpha(*prog))
- {
- while(!isdelim(*prog))
- *temp++ = *prog++;
- token_type = STRING;
- }
- *temp = '\0';
- if(token_type == STRING)
- {
- int i; char* p;
- p = token;
- while(*p)
- { *p = tolower(*p); p++; }
- tok = 0;
- for(i = 0; *TABLE[i].command; i++)
- if(!strcmp(TABLE[i].command, token))
- { tok = (int)TABLE[i].tok; break; }
-
- if(!tok)
- token_type = VARIABLE;
- else
- token_type = COMMAND;
- }
- return token_type;
- }
- ////////////////////////////
- void Slang::putback()
- {
- char* t;
- t = token;
- for(; *t; t++)
- prog--;
- }
- //////////////////////////
- int Slang::isdelim(char c)
- {
- if(strchr(" ;,+-<>/*%^=():[]", c) || c == 9 || c == '\r' || c == 0)
- return 1;
- return 0;
- }
- /////////////////////////
- int Slang::iswhite(char c)
- {
- if(c == ' ' || c == '\t')
- return 1;
- else return 0;
- }
-
-